
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>

#include "../luaParameters.h"
#include "../global.h"
#include <iostream>
#include <boost/filesystem.hpp>
#include <log/log.h>
#include <appendix/phy_constants.h>
#include <boost/signals2/signal.hpp>
#include <boost/bind.hpp>
#include <boost/regex.hpp>
#include <thread>
#include <boost/thread/mutex.hpp>
#include <iostream>
#include <tuple>

namespace LuaHelp{
	sol::table open_luaParameters(sol::this_state L) ;
}

namespace lua{

	template <typename ...Args>
	bool safe_call_lua_function( sol::table module, const std::string& funName, Args&... args){
		sol::protected_function problematic_woof = module[funName];
		auto firstwoof = problematic_woof(module,args...);
		if ( firstwoof.valid() ) {
		}else
		{
			sol::error err = firstwoof;
			std::string what = err.what();
			logs::error_log(boost::format("Call function %1%: %2%") % funName % what);
			return false;
		}
		return true;
	}


	void luaParameters::setGlobalState(std::shared_ptr<luaState> state)
	{
		_globalState = state;
	}

	bool luaParameters::initGlobalState()
	{
		if(_globalState)
		{
			 //std::scoped_lock lk( *( _globalState->mutex() ) );
			 sol::state_view lua( _globalState->state() );

			  std::string code = R"(
				local gap = require "Gallop";
				Gallop = Gallop or gap:new();
				local sweep = require"luaParametersSweep"	
				Gallop.ParametersSweep = Gallop.ParametersSweep or (sweep:new());
				Gallop.ParametersSweep:init_ui();
				Gallop.Parameters = Geometry.Parameters;
				return Gallop.ParametersSweep;
			)";

			  auto result = lua.safe_script(code.c_str(), sol::script_pass_on_error);
			  if (!result.valid()) {
					sol::error err = result;
					logs::error_log(boost::format("Init parameters state: %1%") % err.what());
					return false;
			  }
			  sol::optional<sol::table> maybe_value = result;
			  if( maybe_value.has_value() ){
				  m_parameterSweepModule = *maybe_value;
			  }else{
				  logs::error_log("Init parameters state: table invalide");
				  return false;
			  }
	    }else{
			logs::warning_log("parameters sweep is not initiate,_globalState invalide");
		}

		//parametersSweepSettings(m_sweepSettings);

		//setParametersSweepSettings(m_sweepSettings);

		return true;
	}

	bool luaParameters::parametersSweepSettings(std::map<std::string, std::string>& settings) const
	{
		if(_globalState)
		{
			 std::scoped_lock lk( *( _globalState->mutex() ) );
			 sol::state_view lua( _globalState->state() );
			 safe_call_lua_function(m_parameterSweepModule,"get_settings",settings);
		}else{
			logs::warning_log("parameters sweep is not initiate");
			return false;
		}
		return true;
	}

	bool luaParameters::setParametersSweepSettings(const std::map<std::string, std::string>& settings)
	{
		if(_globalState)
		{
			 std::scoped_lock lk( *( _globalState->mutex() ) );
			 sol::state_view lua( _globalState->state() );

			 safe_call_lua_function(m_parameterSweepModule,"set_settings",settings);

		}else{
			logs::warning_log("parameters sweep is not initiate");
		}
		return false;
	}
};


